#ifndef STRUCTS_H

#define STRUCTS_H

//Simulations Constants
#define MAX_SUBSTREAM 4

#define HOST_QUEUE_TIMER 10
#define ISP_QUEUE_TIMER 10

#define CDN_FLAG -1

#define TRACKER_MIN_PEERS 10
#define MAX_RANK 100

#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include "IPvXAddress.h"
#include "IPAddressResolver.h"

class SubStream {
	int ID;
	int nextChunk;
	int streamID;
	int peerID;
	int rank;
	std::string peerAddr;
	double timestamp;
	bool online;

	public:
	SubStream(int ID, int streamID, int peerID, std::string addr, int rank);
	int getSubStreamID();
	int getStreamID();
	int getPeerID();
	int getRank();
	std::string getPeerAddr();
	double getTimestamp();
	void setTimestamp(double);
	void changePeer(int peerID, std::string addr);
	int getNextChunk();
	bool compareTo(int ID, int streamID, int peerID);
	bool isOnline();
	void setOffline();
	void update();
};

typedef struct {
	unsigned int streamID;
	unsigned int peerID;
	std::string addr;
} streamTrack;

class TrackerTable {
	std::vector<streamTrack> entries;
	
	public:
	TrackerTable();
	bool searchEntry(unsigned int peerID, unsigned int streamID);
	bool searchEntry(std::string addr, unsigned int streamID);
	unsigned int insertEntry(unsigned int peerID, unsigned int streamID, std::string addr);
	void removePeer(unsigned int peerID);
	void removePeerAddr(std::string addr);
	std::vector<unsigned int> getPeersIDs(unsigned int streamID);
	std::vector<std::string> getPeersAddrs(unsigned int streamID);
};

typedef struct {
	std::string address;
	std::string moduleName;
} addressEntry;

class Candidate {
	std::string address;
	double rtt;
	unsigned distance;
	bool used;
	
	public:
	Candidate(std::string addr, double rtt_, double d);
	std::string getAddress() const;
	double getRtt() const;
	double getDistance() const;
	void setRtt(double r);
	void setDistance(double d);
	bool isUsed();
	void setUse(bool);
	
	static double calcMetric(double rtt, double d);
	
	double getMetric() const;
	
	bool operator<(const Candidate&) const;
	bool operator==(const Candidate&) const;
};

#endif
